/**
 * Copyright (C) 2011-2012 Luca Li Greci
 *
 * This file is part of pojo-creator
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.pojocreator.provider;

//Identified as unused import by checkstyle.  
//CHECKSTYLE:OFF
import java.util.Date;

import com.pojocreator.Creator;
import com.pojocreator.provider.collection.RandomFromCollection;
import com.pojocreator.provider.date.RandomDate;
import com.pojocreator.provider.date.RandomFutureDate;
import com.pojocreator.provider.date.RandomPastDate;
import com.pojocreator.provider.number.RandomNumber;
import com.pojocreator.provider.number.SequentialNumber;
import com.pojocreator.provider.string.RandomAlphabetic;
import com.pojocreator.provider.string.RandomChar;

/**
 * This class defines convenient way to access several representation of a
 * {@link DataProvider} which are used to generate the necessary data set.
 * 
 * @author Luca Li Greci
 * 
 * @see Creator#with(String, Object)
 */
public final class Provider {
    private static final DataProvider < String > RANDOM_ALPHABETIC = new RandomAlphabetic();
    private static final DataProvider < Character > RANDOM_CHARACTER = new RandomChar();
    private static final DataProvider < Number > RANDOM_NUMERIC = new RandomNumber < Number >(Number.class);
    private static final DataProvider < Integer > RANDOM_INTEGER = new RandomNumber < Integer >(Integer.class);
    private static final DataProvider < Long > RANDOM_LONG = new RandomNumber < Long >(Long.class);
    private static final DataProvider < Date > RANDOM_DATE = new RandomDate();
    private static final DataProvider < Date > RANDOM_FUTURE_DATE = new RandomFutureDate();
    private static final DataProvider < Date > RANDOM_PAST_DATE = new RandomPastDate();

    /**
     * Provider cannot be instantiate. It just exposes methods to access the
     * necessary {@link DataProvider} implementation.
     */
    private Provider() {
    }

    /**
     * Generate random alphabetic string.
     * 
     * @return a {@link DataProvider} to generate random alphabetic string.
     */
    public static DataProvider < String > randomAlphabetic() {
        return RANDOM_ALPHABETIC;
    }

    /**
     * Generate random number
     * 
     * @return a DataProvider to generate random number
     */
    public static DataProvider < Number > randomNumber() {
        return RANDOM_NUMERIC;
    }

    /**
     * Generate random {@link Integer} number.
     * 
     * @return a DataProvider to generate random {@link Integer} number
     */
    public static DataProvider < Integer > randomIntegerNumber() {
        return RANDOM_INTEGER;
    }

    /**
     * Generate random {@link Long} number.
     * 
     * @return a DataProvider to generate random {@link Long} number
     */
    public static DataProvider < Long > randomLongNumber() {
        return RANDOM_LONG;
    }

    /**
     * Generate a sequence number that starts with 0.
     * 
     * @return a DataProvider to generate a sequence number
     */
    public static DataProvider < Number > sequenceNumber() {
        return new SequentialNumber();
    }

    /**
     * Generate a sequence number that starts with the argument value.
     * 
     * @return a DataProvider to generate a sequence number that starts with a
     *         specified value
     */
    public static DataProvider < Number > sequenceNumber(int startWith) {
        return new SequentialNumber(startWith);
    }

    /**
     * Generate random character.
     * 
     * @return a DataProvider to generate random character
     */
    public static DataProvider < Character > randomCharacter() {
        return RANDOM_CHARACTER;
    }

    /**
     * Extract a random element T among the values passed in as argument
     * 
     * @param values Set of values used to pick up the random element.
     * @param <T> element Data type to provide
     * @return a {@link DataProvider} to extract a random element T.
     */
    public static < T > DataProvider < T > randomFrom(T... values) {
        return new RandomFromCollection < T >(values);
    }

    /**
     * Generate a random date. The returned date can be in the future or in the
     * past.
     * 
     * @return a DataProvider to generate a random {@link Date} in the future or
     *         in the past
     */
    public static DataProvider < Date > randomDate() {
        return RANDOM_DATE;
    }

    /**
     * Generate a random date. The returned date is in the <b>past</b>.
     * 
     * @return a DataProvider to generate a random {@link Date} in the past
     */
    public static DataProvider < Date > randomPastDate() {
        return RANDOM_PAST_DATE;
    }

    /**
     * Generate a random date. The returned date is in the <b>future</b>.
     * 
     * @return a DataProvider to generate a random {@link Date} in the future
     */
    public static DataProvider < Date > randomFutureDate() {
        return RANDOM_FUTURE_DATE;
    }
}
